home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1843 / 1843.xpi / components / firebug-trace-service.js < prev   
Text File  |  2010-01-15  |  12KB  |  384 lines

  1. /* See license.txt for terms of usage */
  2.  
  3. // ************************************************************************************************
  4. // Constants
  5.  
  6. const CLASS_ID = Components.ID("{D2AC51BC-1622-4d4d-85CB-F8E8B5805CB9}");
  7. const CLASS_NAME = "Firebug Trace Console Service";
  8. const CONTRACT_ID = "@joehewitt.com/firebug-trace-service;1";
  9. const EXTENSIONS = "extensions";
  10. const DBG_ = "DBG_";
  11.  
  12. const Cc = Components.classes;
  13. const Ci = Components.interfaces;
  14. const Cr = Components.results;
  15.  
  16. const PrefService = Cc["@mozilla.org/preferences-service;1"];
  17. const prefs = PrefService.getService(Ci.nsIPrefBranch2);
  18. const prefService = PrefService.getService(Ci.nsIPrefService);
  19. const consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
  20.  
  21. const appShellService = Components.classes["@mozilla.org/appshell/appShellService;1"].getService(Components.interfaces.nsIAppShellService);
  22.  
  23. // ************************************************************************************************
  24. // Service implementation
  25.  
  26.  
  27. var toOSConsole = false;
  28.  
  29. TraceConsoleService =
  30. {
  31.     initialize: function() {
  32.         this.observers = [];
  33.         this.optionMaps = {};
  34.  
  35.         // Listen for preferences changes. Trace Options can be changed at run time.
  36.         prefs.addObserver("extensions", this, false);
  37.  
  38.         this.wrappedJSObject = this;
  39.         return this;
  40.     },
  41.  
  42.     osOut: function(str)
  43.     {
  44.         if (!this.outChannel)
  45.         {
  46.             try
  47.             {
  48.                 var appShellService = Components.classes["@mozilla.org/appshell/appShellService;1"].
  49.                     getService(Components.interfaces.nsIAppShellService);
  50.                 this.hiddenWindow = appShellService.hiddenDOMWindow;
  51.                 this.outChannel = "hidden";
  52.             }
  53.             catch(exc)
  54.             {
  55.                 var consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
  56.                 this.outChannel = "service"
  57.                 this.outChannel("Using consoleService because nsIAppShellService.hiddenDOMWindow not available "+exc);
  58.             }
  59.         }
  60.         if (this.outChannel === "hidden")  // apparently can't call via JS function
  61.             this.hiddenWindow.dump(str);
  62.         else
  63.             consoleService.logStringMessage(str);
  64.     },
  65.  
  66.     getTracer: function(prefDomain)
  67.     {
  68.         if (this.getPref("extensions.firebug-tracing-service.DBG_toOSConsole"))
  69.         {
  70.              toOSConsole = true;  // also need browser.dom.window.dump.enabled true
  71.              TraceConsoleService.osOut("TraceConsoleService.getTracer, prefDomain: "+prefDomain+"\n");
  72.         }
  73.  
  74.         if (!this.optionMaps[prefDomain])
  75.             this.optionMaps[prefDomain] = this.createManagedOptionMap(prefDomain);
  76.  
  77.         return this.optionMaps[prefDomain];
  78.     },
  79.  
  80.     createManagedOptionMap: function(prefDomain)
  81.     {
  82.         var optionMap = new TraceBase(prefDomain);
  83.  
  84.         var branch = prefService.getBranch ( prefDomain );
  85.         var arrayDesc = {};
  86.         var children = branch.getChildList("", arrayDesc);
  87.         for (var i = 0; i < children.length; i++)
  88.         {
  89.             var p = children[i];
  90.             var m = p.indexOf("DBG_");
  91.             if (m != -1)
  92.             {
  93.                 var optionName = p.substr(1); // drop leading .
  94.                 optionMap[optionName] = this.getPref(prefDomain+p);
  95.                 if (toOSConsole)
  96.                     this.osOut("TraceConsoleService.createManagedOptionMap "+optionName+"="+optionMap[optionName]+"\n");
  97.             }
  98.         }
  99.  
  100.         return optionMap;
  101.     },
  102.  
  103.     /* nsIObserve */
  104.     observe: function(subject, topic, data)
  105.     {
  106.         if (data.substr(0,EXTENSIONS.length) == EXTENSIONS)
  107.         {
  108.             for (var prefDomain in gTraceService.optionMaps)
  109.             {
  110.                 if (data.substr(0, prefDomain.length) == prefDomain)
  111.                 {
  112.                     var optionName = data.substr(prefDomain.length+1); // skip dot
  113.                     if (optionName.substr(0, DBG_.length) == DBG_)
  114.                         gTraceService.optionMaps[prefDomain][optionName] = this.getPref(data);
  115.                     if (toOSConsole)
  116.                         TraceConsoleService.osOut("TraceConsoleService.observe, prefDomain: "+prefDomain+" optionName "+optionName+"\n");
  117.                 }
  118.             }
  119.         }
  120.     },
  121.  
  122.     getPref: function(prefName)
  123.     {
  124.         var type = prefs.getPrefType(prefName);
  125.         if (type == Ci.nsIPrefBranch.PREF_STRING)
  126.             return prefs.getCharPref(prefName);
  127.         else if (type == Ci.nsIPrefBranch.PREF_INT)
  128.             return prefs.getIntPref(prefName);
  129.         else if (type == Ci.nsIPrefBranch.PREF_BOOL)
  130.             return prefs.getBoolPref(prefName);
  131.     },
  132.  
  133.     // Prepare trace-object and dispatch to all observers.
  134.     dispatch: function(messageType, message, obj, scope)
  135.     {
  136.         // Translate string object.
  137.         if (typeof(obj) == "string") {
  138.             var string = Cc["@mozilla.org/supports-cstring;1"].createInstance(Ci.nsISupportsCString);
  139.             string.data = obj;
  140.             obj = string;
  141.         }
  142.  
  143.         // Create wrapper with message type info.
  144.         var messageInfo = {
  145.             obj: obj,
  146.             type: messageType,
  147.             scope: scope,
  148.             time: (new Date()).getTime()
  149.         };
  150.         if (toOSConsole)
  151.             TraceConsoleService.osOut(messageType+": "+message+"\n");
  152.         // Pass JS object properly through XPConnect.
  153.         var wrappedSubject = {wrappedJSObject: messageInfo};
  154.         gTraceService.notifyObservers(wrappedSubject, "firebug-trace-on-message", message);
  155.     },
  156.  
  157.     /* nsIObserverService */
  158.     addObserver: function(observer, topic, weak)
  159.     {
  160.         if (topic != "firebug-trace-on-message")
  161.             throw Cr.NS_ERROR_INVALID_ARG;
  162.  
  163.         if (this.observers.length == 0) // mark where trace begins.
  164.             lastResort(this.observers, topic, "addObserver");
  165.  
  166.         this.observers.push(observer);
  167.     },
  168.  
  169.     removeObserver: function(observer, topic)
  170.     {
  171.         if (topic != "firebug-trace-on-message")
  172.             throw Cr.NS_ERROR_INVALID_ARG;
  173.  
  174.         for (var i=0; i < this.observers.length; i++) {
  175.             if (this.observers[i] == observer) {
  176.                 this.observers.splice(i, 1);
  177.                 break;
  178.             }
  179.         }
  180.     },
  181.  
  182.     notifyObservers: function(subject, topic, someData)
  183.     {
  184.         if (this.observers.length > 0)
  185.         {
  186.             for (var i=0; i < this.observers.length; i++)
  187.             {
  188.                 try
  189.                 {
  190.                     this.observers[i].observe(subject, topic, someData);
  191.                 }
  192.                 catch (err)
  193.                 {
  194.                     // If it's not possible to distribute the log through registered observers,
  195.                     // use Firefox ErrorConsole. Ultimately the trace-console listens for it
  196.                     // too and so, will display that.
  197.                     var scriptError = Cc["@mozilla.org/scripterror;1"].createInstance(Ci.nsIScriptError);
  198.                     scriptError.init("[JavaScript Error: Failed to notify firebug-trace observers!] " +
  199.                         err.toString(), err.sourceName,
  200.                         err.sourceLine, err.lineNumber, err.columnNumber, err.flags, err.category);
  201.                     consoleService.logMessage(scriptError);
  202.                 }
  203.             }
  204.         }
  205.         else
  206.         {
  207.             lastResort(this.observers, subject, someData);
  208.         }
  209.     },
  210.  
  211.     enumerateObservers: function(topic)
  212.     {
  213.         return null;
  214.     },
  215.  
  216.     /* nsISupports */
  217.     QueryInterface: function(iid)
  218.     {
  219.         if (iid.equals(Ci.nsISupports) ||
  220.             iid.equals(Ci.nsIObserverService))
  221.              return this;
  222.  
  223.         throw Cr.NS_ERROR_NO_INTERFACE;
  224.     }
  225. };
  226.  
  227. function lastResort(listeners, subject, someData)
  228. {
  229.     var unwrapped = subject.wrappedJSObject;
  230.     if (unwrapped)
  231.         var objPart = unwrapped.obj ? (" obj: "+unwrapped.obj) : "";
  232.     else
  233.         var objPart = subject;
  234.  
  235.     TraceConsoleService.osOut("FTS"+listeners.length+": "+someData+" "+objPart+"\n");
  236. }
  237. // ************************************************************************************************
  238. // Public TraceService API
  239.  
  240. // Prevent tracing from code that performs tracing.
  241. var noTrace = false;
  242.  
  243. var TraceAPI = {
  244.     dump: function(messageType, message, obj) {
  245.         if (noTrace)
  246.             return;
  247.  
  248.         noTrace = true;
  249.         try
  250.         {
  251.             gTraceService.dispatch(messageType, message, obj);
  252.         }
  253.         catch(exc)
  254.         {
  255.         }
  256.         finally
  257.         {
  258.             noTrace = false;
  259.         }
  260.     },
  261.  
  262.     sysout: function(message, obj) {
  263.         this.dump(null, message, obj);
  264.     },
  265.  
  266.     setScope: function(scope)
  267.     {
  268.         this.scopeOfFBTrace = scope;
  269.     },
  270.  
  271.     matchesNode: function(node)
  272.     {
  273.         return (node.getAttribute('anonid')=="title-box");
  274.     },
  275.  
  276. };
  277.  
  278. var TraceBase = function(prefDomain) {
  279.     this.prefDomain = prefDomain;
  280. }
  281. //Derive all properties from TraceAPI
  282. for (var p in TraceAPI)
  283.     TraceBase.prototype[p] = TraceAPI[p];
  284.  
  285. TraceBase.prototype.sysout = function(message, obj) {
  286.         if (noTrace)
  287.             return;
  288.  
  289.         noTrace = true;
  290.  
  291.         try
  292.         {
  293.             gTraceService.dispatch(this.prefDomain, message, obj, this.scopeOfFBTrace);
  294.         }
  295.         catch(exc)
  296.         {
  297.             if (toOSConsole)
  298.                 TraceConsoleService.osOut("gTraceService.dispatch FAILS "+exc);
  299.         }
  300.         finally
  301.         {
  302.             noTrace = false;
  303.         }
  304. }
  305.  
  306.  
  307.  
  308.  
  309. // ************************************************************************************************
  310. // Service factory
  311.  
  312. var gTraceService = null;
  313. var TraceConsoleServiceFactory =
  314. {
  315.     createInstance: function (outer, iid)
  316.     {
  317.         if (outer != null)
  318.             throw Cr.NS_ERROR_NO_AGGREGATION;
  319.  
  320.         if (iid.equals(Ci.nsISupports) ||
  321.             iid.equals(Ci.nsIObserverService))
  322.         {
  323.             if (!gTraceService)
  324.                 gTraceService = TraceConsoleService.initialize();
  325.  
  326.             return gTraceService.QueryInterface(iid);
  327.         }
  328.  
  329.         throw Cr.NS_ERROR_NO_INTERFACE;
  330.     },
  331.  
  332.     QueryInterface: function(iid)
  333.     {
  334.         if (iid.equals(Ci.nsISupports) ||
  335.             iid.equals(Ci.nsISupportsWeakReference) ||
  336.             iid.equals(Ci.nsIFactory))
  337.             return this;
  338.  
  339.         throw Cr.NS_ERROR_NO_INTERFACE;
  340.     }
  341. };
  342.  
  343. // ************************************************************************************************
  344. // Module implementation
  345.  
  346. var TraceConsoleServiceModule =
  347. {
  348.     registerSelf: function (compMgr, fileSpec, location, type)
  349.     {
  350.         compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
  351.         compMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME,
  352.             CONTRACT_ID, fileSpec, location, type);
  353.     },
  354.  
  355.     unregisterSelf: function(compMgr, fileSpec, location)
  356.     {
  357.         compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
  358.         compMgr.unregisterFactoryLocation(CLASS_ID, location);
  359.     },
  360.  
  361.     getClassObject: function (compMgr, cid, iid)
  362.     {
  363.         if (!iid.equals(Ci.nsIFactory))
  364.             throw Cr.NS_ERROR_NOT_IMPLEMENTED;
  365.  
  366.         if (cid.equals(CLASS_ID))
  367.             return TraceConsoleServiceFactory;
  368.  
  369.         throw Cr.NS_ERROR_NO_INTERFACE;
  370.     },
  371.  
  372.     canUnload: function(compMgr)
  373.     {
  374.         return true;
  375.     }
  376. };
  377.  
  378. // ************************************************************************************************
  379.  
  380. function NSGetModule(compMgr, fileSpec)
  381. {
  382.     return TraceConsoleServiceModule;
  383. }
  384.